#include "sigslot.h"
#include <iostream>
#include <string>

using namespace sigslot;
/*
typedef template signal2<typename T1, typename T2> signal_t2;
typedef template signal1<typename T1> signal_t2;


template<class T, int I>
class A<T, T*, I>   { };             // #2

A<int, int, 1>   a1;  // uses #1
A<int, int*, 1>  a2;  // uses #2, T is int,
*/


class Window
{
public:
    enum WindowState { Minimized, Normal, Maximized };
    signal_t1<WindowState> StateChanged;
    signal_t2<int, int> MovedTo;
    signal2<int, int> Resized;
    
   
    void SetTitle(const std::string &title)
    {
        m_title = title + "!";
    }
    
    std::string GetTitle() const
    {
        return m_title;
    }
private:
    std::string m_title;
};

class Control
{
public:
    Control() : m_windowState(Window::Normal), m_x(0), m_y(0), m_w(120), m_h(100) {}
protected:
    int m_windowState;
    int m_x;
    int m_y;
    int m_w;
    int m_h;
};

class MyControl : public Control, public has_slots<>
{
public:
    void OnStateChanged(Window::WindowState ws)
    {
        m_windowState = ws;
        
        printf("Oh dios mio, el estado de la ventana ha cambiado!\n");
        printf("Ahora la ventana esta ");
        switch(ws)
        {
            case Window::Minimized:
            printf("chiquitita");
            break;
            case Window::Normal:
            printf("re comun");
            break;
            case Window::Maximized:
            printf("grandecita");
            break;
        }
        printf(".\n");
    }
    
    void OnMove(int x, int y)
    {
        m_x = x;
        m_y = y;
               
        printf("Me han movido a %d, %i!\n", x, y);
    }
    
    void OnResize(int w, int h)
    {
        m_w = w;
        m_h = h;
        
        printf("Me resizearon a %d, %i!\n", w, h);
    }
};



int main ()
{
    printf("Hoa\n");

    Window ventana, ventanita;     // emite señales
    MyControl control, boton;  // tiene slots conectados
    
    ventana.SetTitle("About dialog");
    ventana.StateChanged.connect(&control, &MyControl::OnStateChanged);
    ventana.MovedTo.connect(&control, &MyControl::OnMove);
    ventana.MovedTo.connect(&boton, &MyControl::OnMove);
    ventana.Resized.connect(&control, &MyControl::OnResize);
    
    ventana.MovedTo(34,28);
    
    ventana.MovedTo.disconnect(&control);
    
    ventana.MovedTo.emit(35,28);
    
    control.OnMove(80,90);



    return 0;
}

